// Tencent is pleased to support the open source community by making
// 蓝鲸智云 - 监控平台/日志平台 (BlueKing - Monitor/Log) available.
// Copyright (C) 2017-2022 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//

package oneapm

import (
	"github.com/TencentBlueKing/bkmonitor-kits/logger"
	"go.opentelemetry.io/collector/model/pdata"
	"go.opentelemetry.io/collector/pkg/translator/oneapm"

	"github.com/TencentBlueKing/bk-collector/receiver"
)

type Logger struct {
	logger logger.Logger
}

func (l Logger) Info(key string, value []byte) {
	l.logger.Infof("%v %v", key, value)
}

func (l Logger) Debug(key string, value []byte) {
	l.logger.Debugf("%v %v", key, value)
}

func (l Logger) Error(key string, err error) {
	l.logger.Errorf("%v %v", key, err)
}

func init() {
	l := Logger{logger: logger.StandardLogger()}
	oneapm.InitOne(l, 1024*1024*1024, 20)
}

var Encoders = []receiver.Encoder{JsonEncoder(true), PbEncoder(true)}

// Pb Encoder

func PbEncoder(multi bool) receiver.Encoder {
	return pbEncoder{multi: multi}
}

type pbEncoder struct {
	multi bool
}

func (e pbEncoder) Type() string                               { return "pb" }
func (e pbEncoder) UnmarshalLogs(_ []byte) (pdata.Logs, error) { return pdata.Logs{}, nil }

func (e pbEncoder) UnmarshalTraces(buf []byte) (pdata.Traces, error) {
	if e.multi {
		return oneapm.OneTransactionsToTraces(buf, receiver.ContentTypeProtobuf)
	}
	return oneapm.OneTransactionToTraces(buf, receiver.ContentTypeProtobuf)
}

func (e pbEncoder) UnmarshalMetrics(buf []byte) (pdata.Metrics, error) {
	return oneapm.OneToMetrics(buf, receiver.ContentTypeProtobuf)
}

// Json Encoder

func JsonEncoder(multi bool) receiver.Encoder {
	return jsonEncoder{multi: multi}
}

type jsonEncoder struct {
	multi bool
}

func (e jsonEncoder) Type() string                               { return "json" }
func (e jsonEncoder) UnmarshalLogs(_ []byte) (pdata.Logs, error) { return pdata.Logs{}, nil }

func (e jsonEncoder) UnmarshalTraces(buf []byte) (pdata.Traces, error) {
	if e.multi {
		traces, err := oneapm.OneTransactionsToTraces(buf, receiver.ContentTypeJson)
		return traces, err
	}
	return oneapm.OneTransactionToTraces(buf, receiver.ContentTypeJson)
}

func (e jsonEncoder) UnmarshalMetrics(buf []byte) (pdata.Metrics, error) {
	return oneapm.OneToMetrics(buf, receiver.ContentTypeJson)
}
